﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using DynSim.EntityFramework;
using DynSim.Basics;

namespace DynSim.Entities
{
    [Serializable]
    public class BasicModel : IEntity, IMoveable, IRotatable, IScalable, IHideable, IModel
    {
        public string name { get; set; }

        public Model model { get; set; }
        public Vector3 position { get; set; }
        BaseEngine engine;

        public Vector3 rotation { get; set; }
        public float scale { get; set; }

        public bool show = true;

        public BasicModel(Vector3 position, BaseEngine engine, string assetName, Game game, string name)
        {
            this.name = name;

            this.position = position;
            this.engine = engine;

            this.rotation = new Vector3(0);
            this.scale = 1;

            this.model = game.Content.Load<Model>(assetName);
        }

        public BasicModel(Vector3 position, Vector3 rotation, BaseEngine engine, string assetName, Game game, string name)
        {
            this.name = name;

            this.position = position;
            this.engine = engine;

            this.rotation = rotation;
            this.scale = 1;

            this.model = game.Content.Load<Model>(assetName);
        }

        public BasicModel(Vector3 position, Vector3 rotation, float scale, BaseEngine engine, string assetName, Game game, string name)
        {
            this.name = name;

            this.position = position;
            this.engine = engine;

            this.rotation = rotation;
            this.scale = scale;

            this.model = game.Content.Load<Model>(assetName);
        }

        public void Draw(GameTime gameTime)
        {
            if (show)
            {
                foreach (ModelMesh modelMesh in model.Meshes)
                {
                    Matrix[] transforms = new Matrix[model.Bones.Count];
                    model.CopyAbsoluteBoneTransformsTo(transforms);

                    foreach (BasicEffect effect in modelMesh.Effects)
                    {
                        effect.EnableDefaultLighting();

                        effect.View = engine.camera.view;
                        effect.Projection = engine.camera.projection;
                        effect.World = Matrix.CreateScale(scale) *
                                            Matrix.CreateRotationX(rotation.X) *
                                            Matrix.CreateRotationY(rotation.Y) *
                                            Matrix.CreateRotationZ(rotation.Z) *
                                            Matrix.CreateTranslation(position) *
                                            transforms[modelMesh.ParentBone.Index];
                    }

                    modelMesh.Draw();
                }
            }
        }

        public void Initialize()
        {
            
        }

        public void Update(GameTime gameTime)
        {
            
        }

        public void Scale(float value)
        {
            this.scale = value;
        }

        public void Rotate(Vector3 rotation)
        {
            this.rotation = rotation;
        }

        public void Move(Vector3 position)
        {
            this.position = position;
        }

        public void Show()
        {
            show = true;
        }

        public void Hide()
        {
            show = false;
        }
    }
}
